package service.pqueue;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ServerSessionHandler extends IoHandlerAdapter {

	private static final String OPT_GET = "get";
	private static final String OPT_STAT = "stats";
	private static final String OPT_FLUSH = "flush";
	private static final String OPT_HALT = "halt";
	private static final String OPT_EXIT = "exit";
	private static final String DATA_EMPTY = "";

	private final static Logger LOGGER = LoggerFactory
			.getLogger(ServerSessionHandler.class);

	@Override
	public void messageReceived(IoSession session, Object message) {
		String msg = (String) message;
		if (msg == null || msg.length() <= 0) {
			return;
		}

		if (msg.length() > 5) {
			set(msg);
			return;
		}

		if (OPT_GET.equals(msg)) {
			String ret = get();
			session.write(ret);
			return;
		}

		if (OPT_STAT.equals(msg)) {
			String ret = stats(session.getRemoteAddress().toString());
			session.write(ret);
			return;
		}

		if (OPT_FLUSH.equals(msg)) {
			String ret = flush();
			session.write(ret);
			return;
		}

		if (OPT_EXIT.equals(msg)) {
			exit(session);
			return;
		}

		if (OPT_HALT.equals(msg)) {
			String ret = halt();
			session.write(ret);
			return;
		}

		set(msg);

	}

	private String exit(IoSession session) {
		session.close(true);
		return null;
	}

	private String halt() {
		return "not supported";
	}

	private String flush() {
		QServer.queue.flush();
		return "OK";
	}

	private String stats(String remote) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		StringBuffer sb = new StringBuffer();
		sb.append("--STATS--\r\noffered:");
		sb.append(QServer.queue.statsOffers());
		sb.append("\r\npolled:");
		sb.append(QServer.queue.statsPolls());
		sb.append("\r\nqueue_size:");
		sb.append(QServer.queue.statsLen());
		sb.append("\r\ncurrent_time:");
		sb.append(sdf.format(new Date()));
		sb.append("\r\nopt_client:");
		sb.append(remote);

		return sb.toString();
	}

	private String get() {
		String data = QServer.queue.poll();
		if (data == null) {
			data = DATA_EMPTY;
		}

		LOGGER.info("get:" + data);
		return data;
	}

	private void set(String data) {
		int idx = data.indexOf(" ");
		if (idx > 0 && data.length() > idx) {
			String key = data.substring(0, idx);
			String value = data.substring(idx + 1, data.length());

			QServer.queue.offer(key, value);
			LOGGER.info("set:" + data);
		}
	}

	@Override
	public void sessionIdle(IoSession session, IdleStatus status) {
		LOGGER.info("Disconnecting the idle.");
		// disconnect an idle client
		// session.close(true);
	}

	@Override
	public void exceptionCaught(IoSession session, Throwable cause) {
		// close the connection on exceptional situation
		session.close(true);
	}
}